package lendingbooks.utils;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import android.util.Log;

public class ServiceManager {

	static DefaultHttpClient httpClient = new DefaultHttpClient();

	public static enum SERVICE {
		SEARCH_BY_ISBN, FACEBOOK_SERVER_LOGIN, MY_LIBRARY, ADD_TO_MY_LIBRARY, MY_FRIENDS_LIBRARY, RATE_COPY, DELETE_COPY
	};

	@SuppressWarnings("serial")
	private static final Map<SERVICE, String> SERVICES_MAP = Collections
			.unmodifiableMap(new HashMap<SERVICE, String>() {
				{
					put(SERVICE.SEARCH_BY_ISBN, "http://lending-books.appspot.com/resources/book/isbn/");
					put(SERVICE.FACEBOOK_SERVER_LOGIN, "http://lending-books.appspot.com/android.login.facebook.jsp");
					put(SERVICE.MY_LIBRARY, "http://lending-books.appspot.com/resources/copy/user/");
					put(SERVICE.MY_FRIENDS_LIBRARY, "http://lending-books.appspot.com/resources/copy/user/friends");
					put(SERVICE.ADD_TO_MY_LIBRARY, "http://lending-books.appspot.com/resources/copy/book");
					put(SERVICE.RATE_COPY, "http://lending-books.appspot.com/resources/copy/rate");
					put(SERVICE.DELETE_COPY, "http://lending-books.appspot.com/resources/copy/");
				}
			});

	public String POST(SERVICE p_service, HashMap<String, String> p_params) throws ServiceCallException {
		return this.POST(p_service, p_params, null);
	}

	public String POST(SERVICE p_service, String p_params) throws ServiceCallException {
		return this.POST(p_service, null, p_params);
	}

	public String POST(SERVICE p_service, HashMap<String, String> p_params, String p_urlParam)
			throws ServiceCallException {
		String response = null;
		try {

			URI uri = _GetURI(p_service, p_urlParam);
			HttpPost request = new HttpPost(uri);
			List<NameValuePair> pairs = new ArrayList<NameValuePair>();
			if (p_params != null) {
				for (Entry<String, String> entry : p_params.entrySet()) {
					pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
				}
			}

			request.setEntity(new UrlEncodedFormEntity(pairs));
			HttpResponse httpResponse = httpClient.execute(request);
			HttpEntity httpEntity = httpResponse.getEntity();
			response = EntityUtils.toString(httpEntity);
		} catch (Exception ex) {
			throw new ServiceCallException();
		}
		return response;
	}

	public String PUT(SERVICE p_service, HashMap<String, String> p_params) throws ServiceCallException {
		return this.PUT(p_service, p_params, null);
	}

	public String PUT(SERVICE p_service, String p_params) throws ServiceCallException {
		return this.PUT(p_service, null, p_params);
	}

	public String PUT(SERVICE p_service, HashMap<String, String> p_params, String p_urlParam)
			throws ServiceCallException {
		String response = null;
		try {
			URI uri = _GetURI(p_service, p_urlParam);
			HttpPut request = new HttpPut(uri);
			List<NameValuePair> pairs = new ArrayList<NameValuePair>();
			if (p_params != null) {
				for (Entry<String, String> entry : p_params.entrySet()) {
					pairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
				}
			}
			request.setEntity(new UrlEncodedFormEntity(pairs));
			HttpResponse httpResponse = httpClient.execute(request);
			HttpEntity httpEntity = httpResponse.getEntity();
			response = EntityUtils.toString(httpEntity);
		} catch (Exception ex) {
			throw new ServiceCallException();
		}
		return response;
	}

	public String GET(SERVICE p_service, HashMap<String, String> p_params) throws ServiceCallException {
		return this.GET(p_service, p_params, null);
	}

	public String GET(SERVICE p_service, String p_params) throws ServiceCallException {
		return this.GET(p_service, null, p_params);
	}

	public String GET(SERVICE p_service) throws ServiceCallException {
		return this.GET(p_service, null, null);
	}

	public String GET(SERVICE p_service, HashMap<String, String> p_params, String p_urlParam)
			throws ServiceCallException {
		String response = null;
		try {

			URI uri = _GetURI(p_service, p_urlParam);
			HttpGet request = new HttpGet(uri);
			HttpParams params = new BasicHttpParams();
			if (p_params != null) {
				for (Entry<String, String> entry : p_params.entrySet()) {
					params.setParameter(entry.getKey(), entry.getValue());

				}
			}
			request.setParams(params);
			HttpResponse httpResponse = httpClient.execute(request);
			HttpEntity httpEntity = httpResponse.getEntity();
			response = EntityUtils.toString(httpEntity);

		} catch (Exception ex) {
			System.out.println(ex.getMessage());
			throw new ServiceCallException();
		}
		return response;
	}

	public void DELETE(SERVICE p_service, String p_urlParam) throws ServiceCallException {
		
		try {
			URI uri = _GetURI(p_service, p_urlParam);
			HttpDelete request = new HttpDelete(uri);
			HttpResponse httpResponse = httpClient.execute(request);
			int statusCode = httpResponse.getStatusLine().getStatusCode();
			Log.d("  LENDINGBOOKS ServiceManager.statusCode ", "["+ statusCode + "]");
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
			throw new ServiceCallException();
		}
		
	}

	private URI _GetURI(SERVICE p_service, String p_urlParam) throws URISyntaxException {
		String urlService = SERVICES_MAP.get(p_service);
		
		if (p_urlParam != null) {
			urlService = urlService + p_urlParam;
		}
		Log.d("  LENDINGBOOKS ServiceManager._GetURI ", urlService);
		URI uri = new URI(urlService);
		return uri;
	}

}
